package com.jfinal.plugin.activerecord.freemarker;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class FreeMarkerDbKit {

	/**
	 * The main Config object for system
	 */
	static Configuration configuration = null;

	public static Configuration getConfiguration() {
		return configuration;
	}

	/**
	 * @Title: 创建 Configuration
	 */
	public static Configuration createConfiguration() {
		return createConfiguration("");
	}

	public static Configuration createConfiguration(String basePackage) {
		Configuration cfg = new Configuration(Configuration.getVersion());

		TemplateLoader templateLoader = new ClassTemplateLoader(FreeMarkerDbKit.class.getClassLoader(), basePackage);
		cfg.setTemplateLoader(templateLoader);

		// To avoid formatting numbers using spaces and commas in SQL
		cfg.setNumberFormat("computer");

		// Because it defaults to default system encoding, we should set it always explicitly
		cfg.setDefaultEncoding("utf-8");
		return cfg;
	}

	public static Template resolveSpecifiedTemplate(String sql) {
		return resolveSpecifiedTemplate(getConfiguration(), sql);
	}

	public static Template resolveSpecifiedTemplate(Configuration configuration, String sql) {
		Template template;
		String newSql = sql.trim();
		try {
			if (newSql.contains(" ")) {// Consider that script is inline script
				template = new Template(null, new StringReader(sql), configuration);
			} else {// Consider that script is template name, trying to find the template in classpath
				template = configuration.getTemplate(newSql);
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return template;
	}

	public String process(Template template) {
		return process(template);
	}

	public String process(Template template, Object dataModel) {
		return process(template, dataModel, 2048);
	}

	public String process(Template template, Object dataModel, int initialSize) {
		Writer out = new StringWriter(initialSize);
		try {
			template.process(dataModel, out);
			return out.toString().replaceAll("[\\n\\r]", "");
		} catch (TemplateException e) {
			throw new RuntimeException(e);
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				out.flush();
			} catch (IOException e) {
				// ignore
			}
		}
	}
}
